﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Web;
using System.Web.Script.Serialization;
using Medianamik.Core;
using Medianamik.UI.Web.Shop.Data;
using Medianamik.UI.Web.Shop.Data.Dto;
using Medianamik.UI.Web.Shop.Data.Interfaces;
using Medianamik.UI.Web.Shop.Data.Repositories;
using Medianamik.UI.Web.MVP.Presentation;
using Medianamik.UI.Web.Shop.Services;
using Medianamik.UI.Web.Shop.Services;
using IAddress = Medianamik.UI.Web.Shop.Data.Interfaces.IAddress;
using IClientProfile = Medianamik.UI.Web.Shop.Data.Interfaces.IClientProfile;
using IModel = Medianamik.UI.Web.Shop.Data.Interfaces.IModel;
using IOrderItem = Medianamik.UI.Web.Shop.Data.Interfaces.IOrderItem;
using IProduct = Medianamik.UI.Web.Shop.Data.Interfaces.IProduct;
using IRegion = Medianamik.UI.Web.Shop.Data.Interfaces.IRegion;

namespace Medianamik.UI.Web.Shop.Presentation.Presenters
{
    public class OrderEditPresenter<TView, TOrder, TClientProfile, TOrderItem, TShoppingCart,
        TShoppingCartItem, TModel, TAddress, TProduct, TShoppingCartItemWithModels,TRegion> : ModulePresenter<TView>
        where TView : IOrderEdit<TOrder, TClientProfile, TOrderItem, TAddress>
        where TClientProfile : IClientProfile
        where TOrder : IOrder<TOrderItem>
        where TOrderItem : IOrderItem
        where TShoppingCart : IShoppingCart<TShoppingCartItem, TModel>
        where TModel : IModel
        where TShoppingCartItem : IShoppingCartItem<TModel>
        where TAddress : IAddress
        where TProduct : IProduct
        where TShoppingCartItemWithModels : IShoppingCartItemWithModels<TModel>
        where TRegion : IRegion
    {
        public OrderEditPresenter(TView view, IOrderRepository<TOrder, TOrderItem> orderRepository,
            IOrderService<TOrder, TOrderItem, TShoppingCart, TShoppingCartItem,
            TProduct, TModel, TShoppingCartItemWithModels> orderService,
            IClientProfileRepository<TClientProfile> clientProfileRepository,
            IAddressRepository<TAddress> addressRepository,
            IRegionRepository<TRegion> regionRepository,
            IOrderItemRepository<TOrderItem> orderItemRepository )
            : base(view)
        {
            OrderRepository = orderRepository;
            OrderService = orderService;
            ClientProfileRepository = clientProfileRepository;
            AddressRepository = addressRepository;
            RegionRepository = regionRepository;
            OrderItemRepository = orderItemRepository;
        }

        protected void View_SaveClicked(object sender, EventArgs e)
        {
            CurrentOrder.Notes = View.Notes;
            CurrentOrder.ShippedDate = View.ShippedDate;
            OrderService.SaveOrder(CurrentOrder);
            OnViewLoaded();
            View.Redirect(View.ReturnUrl);
        }

        protected readonly IOrderItemRepository<TOrderItem> OrderItemRepository;

        protected readonly IOrderRepository<TOrder, TOrderItem> OrderRepository;

        protected readonly IOrderService<TOrder, TOrderItem, TShoppingCart, TShoppingCartItem,
            TProduct, TModel, TShoppingCartItemWithModels>
            OrderService;

        protected readonly IClientProfileRepository<TClientProfile> ClientProfileRepository;

        protected readonly IAddressRepository<TAddress> AddressRepository;

        protected readonly IRegionRepository<TRegion> RegionRepository;

        public readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();

        private TView ShopView
        {
            get { return ((TView)View); }
        }

        protected override void Initialize(object sender, EventArgs e)
        {
            base.Initialize(sender, e);

            View.SaveButton.Click += View_SaveClicked;
            View.CancelButton.NavigateUrl += View.ReturnUrl;

            if (!View.IsPostBack)
            {
                OnViewLoaded();
            }
        }

        protected virtual void OnViewLoaded()
        {
            BindTaxesRepeater();
            BindOrderItemsRepeater();
            View.Order = CurrentOrder;
            View.ClientProfile = CurrentClientProfile;
            View.Shipping = CurrentShipping;
            View.DeliveryAddress = ClientDeliveryAddress;
            View.PaymentAddress = ClientPaymentAddress;
            View.ShippedDate = CurrentOrder.ShippedDate;
            View.Notes = CurrentOrder.Notes;

        }

        protected virtual void BindOrderItemsRepeater()
        {
            ShopView.OrderItems = OrderItemRepository.ChildsOf(CurrentOrder.NodeId, false, 0);
        }

        protected virtual void BindTaxesRepeater()
        {
            ShopView.Taxes = GetTaxes();
        }

        protected virtual IList<TaxDTO> GetTaxes()
        {
            return Serializer.Deserialize<List<TaxDTO>>(CurrentOrder.Taxes);
        }

        private Guid? _orderId;
        protected virtual Guid? OrderId
        {
            get
            {
                return _orderId ?? (_orderId = new Guid(HttpContext.Current.Request.QueryString.GetValues("nodeid")[0]));
            }
        }

        private ShippingDTO _shipping;
        protected virtual ShippingDTO CurrentShipping
        {
            get { return _shipping ?? (_shipping = GetShipping()); }
        }
        protected virtual ShippingDTO GetShipping()
        {
            return Serializer.Deserialize<ShippingDTO>(CurrentOrder.Shipping);
        }

        private TOrder _currentOrder;
        protected virtual TOrder CurrentOrder
        {
            get
            {
                return _currentOrder = _currentOrder == null ?
                    OrderRepository.Get(OrderId.Value,CultureInfo.InvariantCulture,
                    ContentState.Draft, ActiveStatus.All) : _currentOrder;
            }
        }

        #region Client
        private TClientProfile _clientProfile;
        protected virtual TClientProfile CurrentClientProfile
        {
            get
            {
                return _clientProfile =  _clientProfile == null ? GetClientProfile():_clientProfile ;
            }
        }
        protected virtual TClientProfile GetClientProfile()
        {
            return ClientProfileRepository.Get(CurrentOrder.ClientProfile.GetValueOrDefault());
        }

        private TAddress _clientPaymentAddress;
        protected virtual TAddress ClientPaymentAddress
        {
            get
            {
                return _clientPaymentAddress = _clientPaymentAddress == null ?
                    GetClientPaymentAddress() : _clientPaymentAddress;
            }
        }

        protected virtual TAddress GetClientPaymentAddress()
        {
            return AddressRepository.Get(CurrentClientProfile.PaymentAddress.GetValueOrDefault());
        }

        private TAddress _clientDeliveryAddress;
        protected virtual TAddress ClientDeliveryAddress
        {
            get {
                return _clientDeliveryAddress = _clientDeliveryAddress == null ?
                    GetClientDeliveryAddress() : _clientDeliveryAddress;
            }
        }

        protected virtual TAddress GetClientDeliveryAddress()
        {
            return AddressRepository.Get(CurrentClientProfile.DeliveryAddress.GetValueOrDefault());
        }

        protected virtual string ClientPaymentState
        {
            get
            {
                return RegionRepository.Get(ClientPaymentAddress.State.GetValueOrDefault()).Name;
            }
        }

        protected virtual string ClientDeliveryState
        {
            get
            {
                return RegionRepository.Get(ClientDeliveryAddress.State.GetValueOrDefault()).Name;
            }
        }
        #endregion Client
    }

    public class OrderEditPresenter : OrderEditPresenter<IOrderEdit, Order, ClientProfile, OrderItem, ShoppingCart,
        ShoppingCartItem, Model, Address, BaseProduct, ShoppingCartItemWithModels, Region>
    {
        public OrderEditPresenter(IOrderEdit view, IOrderRepository<Order, OrderItem> orderRepository, IOrderService<Order, OrderItem, ShoppingCart, ShoppingCartItem, BaseProduct, Model, ShoppingCartItemWithModels> orderService, IClientProfileRepository<ClientProfile> clientProfileRepository, IAddressRepository<Address> addressRepository, IRegionRepository<Region> regionRepository, IOrderItemRepository<OrderItem> orderItemRepository)
            : base(view, orderRepository, orderService, clientProfileRepository, addressRepository, regionRepository, orderItemRepository)
        {
        }
    }
}
